#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>


struct msgbuf {
	long mtype;   		/* 消息类型，必须大于0 */
	char mtext[128];	/* 消息数据 */
};

typedef int (*process)(void *arg);

pid_t create_process(process entry, void *arg)
{
	int exit_value;
	pid_t pid;
	
	if(!entry)
		return -1;
	
	//创建子进程
	pid = fork();
	if(pid == 0)
	{
		//fork在子进程中返回0
		exit_value = entry(arg);
		exit(exit_value);
	}
	//fork在父进程中返回子进程的ID
	return pid;
}

int receive_process(void *arg)
{
	int msg_id;
	key_t key;
	struct msgbuf msg;
	
	//生成key值
	key = ftok("/", 0);
	if(key == -1)
	{
		perror("ftok");
		return -1;
	}
	//创建消息队列
	msg_id = msgget(key, IPC_CREAT|0666);
	if(msg_id == -1)
	{
		perror("msgget");
		return -1;
	}
	
	while(1)
	{
		memset(&msg, 0, sizeof(msg));
		if(msgrcv(msg_id, &msg, sizeof(msg.mtext), 0x00, 0) != -1)
			printf("%s", msg.mtext);
		else
			printf("wait message failed\n");
	}
}

int transmit_process(void *arg)
{
	int i;
	int msg_id;
	key_t key;
	struct msgbuf msg;
	
	//生成key值
	key = ftok("/", 0);
	if(key == -1)
	{
		perror("ftok");
		return -1;
	}
	//创建消息队列
	msg_id = msgget(key, IPC_CREAT|0666);
	if(msg_id == -1)
	{
		perror("msgget");
		return -1;
	}
	
	i=0;
	while(1)
	{
		i++;
		snprintf(msg.mtext, sizeof(msg.mtext), "message test,%d\r\n", i);
		if(msgsnd(msg_id, &msg, sizeof(msg.mtext), 0) == -1)
			printf("wait message failed\n");
		sleep(1);
	}
}

int main(int argv, char *argc[])
{
	pid_t pid1,pid2;
	
	
	//同时创建的进程其执行的先后顺序不确定
	pid1 = create_process(receive_process, "receive_process;");
	printf("receive_process PID=%d\r\n", pid1);
	
	pid2 = create_process(transmit_process, "transmit_process;");
	printf("transmit_process PID=%d\r\n", pid2);
	
	while(1)
	{
		sleep(10);
	}
}
